import json
import os
import re
import subprocess

from util.user_log import log


class Cmds:
    check_5037 = 'netstat -ano | findstr 5037'
    check_port = 'netstat -ano | findstr {}'
    devices = 'adb devices'
    set_tcpip = 'adb -s {} tcpip {}'
    ipconfig = 'adb shell ifconfig wlan0'
    connect = 'adb connect {}'
    dis_connect = 'adb disconnect {}'
    a01 = 'adb tcpip 5503'

    @staticmethod
    def execute(command, get_res=False, timeout=4):
        log.debug('执行cmd：{}'.format(command))
        p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
        try:
            p.wait(timeout)
        except subprocess.TimeoutExpired:
            p.kill()
            raise Exception('超时！请检查命令参数是否正确: \n{}'.format(command))
        reads = str(p.stdout.read(), encoding='utf-8')
        read_lines = [i for i in reads.split('\r\n') if i]
        log.debug(read_lines)
        if get_res:
            return reads
        return read_lines


class Connect(Cmds):
    def __init__(self):
        self.devices_list = self.__get_devicesName()
        self.disConnest_list = []
        self.port_list = []

    def __get_devicesName(self) -> list:
        res_li = self.execute(self.devices)
        name_li = []
        for i in res_li:
            if '\tdevice' in i:
                name = i.split('\t')[0]
                name_li.append(name)
        return name_li

    def exe_tcpIp(self, name_li, port):
        name = name_li[0]
        cmd = self.set_tcpip.format(name, port)
        self.execute(cmd)
        return None

    def exe_connect(self, ip, port):
        ip_port = f'{ip}:{port}'
        cmd = self.connect.format(ip_port)
        res = self.execute(cmd, get_res=True)
        return res

    def exe_disConnect(self, res_li):
        log.debug(res_li)
        if not len(res_li) > 1:
            return None
        log.debug('先取消已经连接的')
        for i in res_li:
            log.debug(i)
            if ':' in i:
                log.debug(i)
                cmd = self.dis_connect.format(i)
                self.execute(cmd)
                self.disConnest_list.append(i)
                self.port_list.append(i.split(':')[1])

    def get_ip(self) -> str:
        res_li = self.execute(self.ipconfig)
        ip = None
        for i in res_li:
            if 'inet addr' in i:
                ip = re.search(r'inet addr:(.+?)\s', i)[1]
        if not ip:
            raise Exception(f'adb连接了多台设备，无法获取ip地址！'
                            f'请先取消其他设备的连接。\n{self.devices_list}')
        return ip

    def get_port(self, port):
        step = 1
        for i in range(1, 10):
            if str(port) in self.port_list:
                port += step
        return port

    def main(self):
        # 已经连接: 由于存在多台设备时无法查看ip，所有不能判断是否重复连接
        port = 5501
        res_li = self.devices_list  # 获取devices列表
        self.exe_disConnect(res_li)  # 把已经远程连接的先解除
        ip = self.get_ip()  # 获取ip和port（唯一的）
        port = self.get_port(port)
        res = self.exe_connect(ip, port)  # 首先直接远程连接
        self.main_02(res, ip, port, res_li)  # 如果直接连接不了，再执行tcpip
        self.teardown()  # 把之前解除了连接的，重新连接；并输出最终的连接结果

    def main_02(self, res, ip, port, res_li):
        if 'connected' in res:
            print(f'{res}连接成功!')
        elif 'no such device' or 'cannot connect' in res:
            self.exe_tcpIp(res_li, port)
            res = self.exe_connect(ip, port)
            print(f'{res}连接成功!')
        else:
            return print(f'{res}连接失败!')
        self.teardown()

    def teardown(self):
        log.debug('重新连接刚才取消的')
        for i in self.disConnest_list:
            self.execute(self.connect.format(i))
        _return = self.execute(self.devices, get_res=True)
        # print(_return)


if __name__ == '__main__':
    conn = Connect()
    conn.main()
